"""   Copyright 2011 Bart Enkelaar

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
"""

from lyricbuilder import Line, Match, SongBuilder
import unittest

class TestFindLine(unittest.TestCase):
    def setUp(self):
        self.builder = SongBuilder("geektrip")
        self.sentence = "Geektrip is pretty awesome"
        
    def testSingleLine(self):
        input = [self.sentence] * 15
        self.assertEquals({self.sentence: Line(self.sentence, 15)}, self.builder.weigh(input))
        
    def testTwoLines(self):
        sentence2 = "I have fun at the #geektrip"
        input = [self.sentence] * 8 + [sentence2] * 7
        self.assertEquals({self.sentence: Line(self.sentence, 8), sentence2: Line(sentence2, 7)},
                          self.builder.weigh(input))
        
    def testAddToDict(self):
        dictionary = {self.sentence: Line(self.sentence, 4)}
        self.builder.weigh([self.sentence]*3, dictionary)
        self.assertEquals(7, dictionary[self.sentence].weight)


class TestLineCompare(unittest.TestCase):
    def setUp(self):
        self.line = Line("You know it's all about the dream", 3)
    
    def testWeight(self):
        self.assertEquals(True, Line("Reviews", 5) > self.line)
        self.assertEquals(True, Line("Reviews", 2) < self.line)

    def testSentenceLength(self):
        self.assertEquals(True, self.line < 
            Line("I wish I could heal you and I wish you could heal me", 3))
        self.assertEquals(True, Line("Reviews", 3) < self.line)

    def testEqual(self):
        self.assertEquals(False, Line("Reviews", 3) < Line("Reviews", 3))
        self.assertEquals(False, Line("Reviews", 3) > Line("Reviews", 3))

    def testSort(self):
        line1 = Line("Ab", 4)
        line2 = Line("Ab", 3)
        line3 = Line("A", 3)
        line4 = Line("Ab", 2)
        line5 = Line("Abcdefg", 1)
        input = [line4, line3, line1, line2, line5]
        self.assertEquals([line1, line2, line3, line4, line5],
                          sorted(input, reverse=True)) 
    

class TestMatchCompare(unittest.TestCase):
    def testDifference(self):
        match1 = Match(Line("Forget the balloons, I get the solution BMX", 7),
                       Line("Forget the malloons, I get no solution", 7))
        match2 = Match(Line("Forget the balloons", 7),
                       Line("Forget the malloons, I get the solution BMX", 7))
        self.assertEquals(True, match2 < match1)

    def testWeight(self):
        match1 = Match(Line("Forget the balloons", 5),
                       Line("Forget the malloons", 9))
        match2 = Match(Line("Forget the balloons", 3),
                       Line("Forget the malloons", 7))
        self.assertEquals(True, match2 < match1)

    def testDifferenceAfterAll(self):
        match1 = Match(Line("Forget the balloonsa", 7),
                       Line("Forget the malloons", 7))
        match2 = Match(Line("Forget the balloons", 7),
                       Line("Forget the malloons", 7))
        self.assertEquals(True, match2 > match1)

    def testEquals(self):
        match1 = Match(Line("Forget the balloons", 7),
                       Line("Forget the malloons", 7))
        match2 = Match(Line("Forget the balloons", 7),
                       Line("Forget the malloons", 7))
        self.assertEquals(False, match2 < match1)
#        TODO This next assertion should work as well
#        self.assertEquals(False, match2 > match1)



class TestMatchDetermining(unittest.TestCase):
    def setUp(self):
        self.builder = SongBuilder("geektrip")
        self.base_line = Line("One other knife", 5)
        self.best_line = Line("for strife", 4)
    
    def testPickWeightiestMatch(self):
        input = [self.base_line, self.best_line, Line("One other fife", 3)]
        self.assertEquals([Match(self.base_line, self.best_line)],
                          self.builder._find_all_matches(input))

    def testPickBestFittingMatch(self):
        bone_line = Line("One other fife", 4)
        input = [self.base_line, self.best_line, bone_line]
        self.assertEquals([Match(self.base_line, bone_line)],
                          self.builder._find_all_matches(input))


from lyricbuilder import RhymeMatcher
    
class TestRhymeMatcher(unittest.TestCase):
    def setUp(self):
        self.matcher = RhymeMatcher(Line("I like cake"))

    def testNoRhymeSinceSame(self):
        self.assertEquals(False, self.matcher.matches(Line("And more cake")))

    def testNoRhymeSinceSameCI(self):
        self.assertEquals(False, self.matcher.matches(Line("And more CAKE")))

    def testRhymeCI(self):
        self.assertEquals(True, self.matcher.matches(Line("I'LL BE FAKE")))

    def testBasicRhyme(self):
        self.assertEquals(True, self.matcher.matches(Line("I'm a flake")))
        self.assertEquals(False, self.matcher.matches(Line("So I bake in my oven")))

    def testMoreRhyme(self):
        self.assertEquals(True, self.matcher.matches(Line("So I stay awake")))
        self.assertEquals(True, RhymeMatcher(Line("I go to sleep"))
                                    .matches(Line("So I say meep meep")))

    def testNonRhyme(self):
        self.assertEquals(False, RhymeMatcher(Line("kfdgdl,j"))
                                    .matches(Line("tghkjb")))
    
    def testDetermineRhymeSyllable(self):
        self.assertEquals("ake", self.matcher._determine_rhyme("cake"))
        self.assertEquals("ick", self.matcher._determine_rhyme("thick"))
        self.assertEquals("ook", self.matcher._determine_rhyme("book"))
    
    def testDetermineRhymeNoMatch(self):
        self.assertEquals(None, self.matcher._determine_rhyme("cklnz"))
        
    def testDetermineShortRhymeSyllable(self):
        self.assertEquals("oo", self.matcher._determine_rhyme("coo"))
        self.assertEquals("ay", self.matcher._determine_rhyme("sway"))
        self.assertEquals("ea", self.matcher._determine_rhyme("sea"))
        
    def testSilentEs(self):
        self.assertEquals("omen", self.matcher._determine_rhyme("omen"))
        self.assertEquals("ames", self.matcher._determine_rhyme("games"))
        self.assertEquals("ickey", self.matcher._determine_rhyme("stickey"))
    
    def testFindLastWord(self):
        self.assertEquals("meep",
                          self.matcher._find_last_word("Wolla wolla way meep!")) 
    


if __name__ == "__main__":
    unittest.main()